package net.sunbeta.test.util ;

import java.io.BufferedInputStream ;
import java.io.BufferedOutputStream ;
import java.io.File ;
import java.io.FileOutputStream ;
import java.io.IOException ;
import java.io.UnsupportedEncodingException ;
import java.net.MalformedURLException ;
import java.net.URISyntaxException ;
import java.net.URL ;
import java.net.URLDecoder ;
import java.util.ArrayList ;
import java.util.List ;

import org.apache.commons.io.FileUtils ;
import org.apache.commons.io.LineIterator ;
import org.apache.commons.lang.StringUtils ;
import org.apache.commons.logging.Log ;
import org.apache.commons.logging.LogFactory ;

public class DownloadUtil {
    private static final Log log = LogFactory.getLog(DownloadUtil.class) ;

    public static void download(String uri, File target) throws MalformedURLException, IOException {
        download(new URL(uri), target) ;
    }

    public static void download(URL url, File target) throws IOException {
        log.debug("Downloading " + url + " to " + target.getAbsolutePath()) ;
        if (url.getProtocol().equalsIgnoreCase("file")) {
            // file copy
            File sourceFile ;
            try {
                sourceFile = new File(url.toURI()) ;
            } catch (URISyntaxException e) {
                sourceFile = new File(url.getPath()) ;
            }
            if (target.exists()) {
                FileUtils.deleteQuietly(target) ;
            }
            FileUtils.copyDirectory(sourceFile, target) ;
        } else {
            // network download

            //System.out.println(FileUtils.toFile(url).getName()) ;
            BufferedInputStream in = new BufferedInputStream(url.openStream()) ;
            FileOutputStream out = new FileOutputStream(target) ;
            BufferedOutputStream bout = new BufferedOutputStream(out, 1024) ;
            byte data[] = new byte[1024] ;
            int count ;
            while ((count = in.read(data, 0, 1024)) != -1) {
                bout.write(data, 0, count) ;
            }
            bout.close() ;
            out.close() ;
            in.close() ;
        }
    }

    public static void downloadDirectory(URL urlpath, String targetpath) throws IOException {
        System.setProperty("java.net.useSystemProxies", "true") ;
        System.setProperty("http.proxyHost", "lonnetcache.lehman.com") ;
        System.setProperty("http.proxyPort", "80") ;

        File targetFolder = new File(targetpath) ;
        if (!targetFolder.exists()) {
            targetFolder.mkdir() ;
        }
        log.debug("Downloading " + urlpath + " to " + targetpath) ;

        String subFolderName = getSubFolderName(urlpath.toString()) ;
        if (urlpath.getProtocol().equalsIgnoreCase("http")) {
            // file copy
            try {
                File booksFile = new File("c:\\books.txt") ;
                FileUtils.copyURLToFile(urlpath, booksFile) ;
                LineIterator it = FileUtils.lineIterator(booksFile, "UTF-8") ;
                while (it.hasNext()) {

                    String lineString = it.nextLine() ;
                    int start = lineString.toString().indexOf("<a href=\"") ;
                    int end = getBooksTypeIndex(lineString) ;
                    if (start == -1 || end == -1)
                        continue ;
                    String downUrl = lineString.toString().substring(start + 9, end) ;
                    if (downUrl.contains("<a href=\"")) {
                        downUrl = downUrl.substring(downUrl.indexOf("<a href=\"", 9) + 9) ;
                    }
                    String fileName = getDecodeName(downUrl) ;

                    File targetFile = new File("c:\\sunxbooks\\" + subFolderName + "\\" + fileName) ;
                    System.out.println("Downloading the file: " + targetFile.getName()) ;
                    if (!targetFile.getParentFile().exists()) {
                        targetFile.getParentFile().mkdir() ;
                    }
                    FileUtils.touch(targetFile) ;
                    download(urlpath + downUrl, targetFile) ;
                    System.out.println("Finished it") ;
                }

                File eBookspath = new File("D:\\eBooks\\" + subFolderName + "\\") ;
                File downPath = new File("c:\\sunxbooks\\" + subFolderName + "\\") ;

                if (!eBookspath.exists()) {
                    eBookspath.mkdir() ;
                }
                FileUtils.copyDirectory(downPath, eBookspath) ;
            } catch (Exception e) {
                e.printStackTrace() ;
            }
        }
    }

    private static String getDecodeName(String downUrl) {
        CharTools charTools = new CharTools() ;
        if (charTools.isUtf8Url(downUrl)) {
            return charTools.Utf8URLdecode(downUrl) ;
        } else {
            try {
                return URLDecoder.decode(downUrl, "GB2312") ;
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException("Cannot decode this file name!", e) ;
            }
        }
    }

    private static int getBooksTypeIndex(Object lineString) {
        List fileTypes = new ArrayList() ;
        fileTypes.add("pdf\">") ;
        fileTypes.add("zip\">") ;
        fileTypes.add("chm\">") ;
        fileTypes.add("rar\">") ;
        fileTypes.add("ppt\">") ;
        fileTypes.add("pptx\">") ;

        int typeIndex = -1 ;
        for (Object type : fileTypes) {
            typeIndex = lineString.toString().indexOf(type.toString()) ;
            if (typeIndex != -1) {
                break ;
            }
        }

        if (typeIndex != -1) {
            if (lineString.toString().contains("pptx\">")) {
                typeIndex += 4 ;
            } else {
                typeIndex += 3 ;
            }
        }

        return typeIndex ;
    }

    public static void main(String[] args) throws MalformedURLException, IOException {
        downloadDirectory(new URL("http://mirrors.sohu.com/ebook/vpn/"), "c:/books") ;
    }

    public static String getSubFolderName(String url) {
        String[] ee = StringUtils.split(url, "/") ;
        return ee[ee.length - 1] ;
    }
}
